package stalker.user;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;

import junit.framework.Assert;
import message.Message;
import message.MessageParser;
import message.types.data.AddDataRequest;
import message.types.none.GetLastDataRequest;
import message.types.stalker.RegisterRequest;
import network.e2e.FrameReader;
import network.e2e.FrameWriter;
import network.link.FrameInputStream;
import network.link.FrameOutputStream;

import org.junit.Test;

import stalker.room.PrivatePersistentRoom;
import stalker.room.Room;
import data.content.ContentSentence;

/**
 * JUnit for User.java and Catalog.java
 * @deprecated it is not feasible to keep updating this with Stalker
 */

public class UserTest {

  User old_user;
  
  public void verifyOldUser() {
    Assert.assertEquals("User:getUserID fail", old_user.getID(), 3L);
    Assert.assertEquals("User:getUsername fail", old_user.getName(), "Listiarso Wastuargo");
    Assert.assertEquals("User:toString fail", old_user.toString(), "Listiarso Wastuargo");
    Assert.assertTrue("User:equals fail", old_user.equals(old_user));
    Assert.assertFalse("User:equals fail", old_user.equals(null));
    Assert.assertFalse("User:equals fail", old_user.equals((Integer)5));
  }
  
  @Test
  public void testNewUser() {
    Assert.assertFalse("Catalog:isTaken fails", User.isTaken("Listiarso Wastuargo"));
    old_user = User.createUser("Listiarso Wastuargo");
    Assert.assertTrue("Catalog:isTaken fails", User.isTaken("Listiarso Wastuargo"));

    Assert.assertEquals("Catalog:getUser fails", old_user, User.getUserFromID(4L));
    verifyOldUser();
    
    Calendar before = new GregorianCalendar();
    User new_user = User.createUser("Irvan");
    Calendar after = new GregorianCalendar();
    Assert.assertEquals("Catalog:getUser fails", new_user, User.getUserFromID(4L));
    Assert.assertEquals("Catalog:getUser fails", old_user, User.getUserFromID(3L));
    Assert.assertTrue("User:getCreationCalendar fail",
        new_user.getCreationCalendar().compareTo(before) >= 0);
    Assert.assertTrue("User:getCreationCalendar fail",
        new_user.getCreationCalendar().compareTo(after) <= 0);
    Assert.assertEquals("User:getUserID fail", new_user.getID(), 4L);
    Assert.assertEquals("User:getName fail", new_user.getName(), "Irvan");
    Assert.assertEquals("User:toString fail", new_user.toString(), "Irvan");
    Assert.assertTrue("User:equals fail", new_user.equals(new_user));
    Assert.assertFalse("User:equals fail", new_user.equals(null));
    Assert.assertFalse("User:equals fail", new_user.equals((Integer)5));
    Assert.assertFalse("User:equals fail", new_user.equals(old_user));
    Assert.assertFalse("User:equals fail", old_user.equals(new_user));
    Assert.assertTrue("User:getUserFromUsername fails",
        new_user == User.getUserFromName("Irvan"));
    verifyOldUser();
  }

  @Test(expected=AssertionError.class)
  public void testRetryUsername() {
    User new_user = User.createUser("Listiarso Wastuargo");
    System.out.println(new_user);
  }
  
  @Test(expected=AssertionError.class)
  public void testNullUsername() {
    User new_user = User.createUser(null);
    System.out.println(new_user);
  }
  
  @Test(expected=AssertionError.class)
  public void testOutOfRangeUser() {
    User user = User.getUserFromID(5L);
    System.out.println(user);
  }
  
  @Test(expected=AssertionError.class)
  public void testZeroUserId() {
    User new_user = User.getUserFromID(0L);
    System.out.println(new_user);
  }
  
  /**
   * Tests for user connection
   * @throws IOException 
   */
  @Test
  public void testUserConnection() throws IOException {
    User apel = User.createUser("Manusia 1/2 Apel");
    Room ruang = PrivatePersistentRoom.create("Just Fruity!");
    Message test = new RegisterRequest(apel, ruang);
    
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    FrameWriter fw = new FrameWriter(new FrameOutputStream(os));
    
    //register
    MessageParser.send(test, fw);
    
    //asks for last data
    MessageParser.send(new GetLastDataRequest(apel, ruang), fw);
    
    //writes something
    MessageParser.send(new AddDataRequest(apel, ruang, new ContentSentence("Saya apel!")), fw);
    
    //asks for last data
    MessageParser.send(new GetLastDataRequest(apel, ruang), fw);
    
    //writes something
    MessageParser.send(new AddDataRequest(apel, ruang, new ContentSentence("Saya kuman!")), fw);
    
    //asks for last data
    MessageParser.send(new GetLastDataRequest(apel, ruang), fw);
    
    FrameReader fr = new FrameReader(new FrameInputStream(new ByteArrayInputStream(os.toByteArray())));
    
    System.out.println(os.toString());
    
    ByteArrayOutputStream osnet = new ByteArrayOutputStream();
    
    apel.activate(fr, new FrameWriter(new FrameOutputStream(osnet)));
    
    //System.out.println("Ending");
    try {
      Thread.sleep(100);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    System.out.println(osnet.toString());
    
//    Assert.assertEquals(stalk, test);
  }

}
